package org.scohen.juploadr.app.scalers;

import java.io.File;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.swt.graphics.Point;
import org.scohen.juploadr.Messages;
import org.scohen.juploadr.ui.MessageUtils;

import au.com.lastweekend.jim.io.exif.ExifDirectory;
import au.com.lastweekend.jim.io.exif.ExifInteropDirectory;
import au.com.lastweekend.jim.io.exif.GPSDirectory;
import au.com.lastweekend.jim.io.exif.RawExifDirectory;
import au.com.lastweekend.jim.io.exif.ThumbnailTiffDirectory;
import au.com.lastweekend.jim.io.exif.TiffDirectory;
import au.com.lastweekend.jim.io.exif.TiffTagFormat;
import au.com.lastweekend.jim.io.exif.makernote.UnknownMakernoteDirectory;
import au.com.lastweekend.jim.io.exif.makernote.canon.CanonMakernoteDirectory;
import au.com.lastweekend.jim.io.exif.makernote.casio.CasioMakernoteDirectory;
import au.com.lastweekend.jim.io.exif.makernote.fujifilm.FujiFilmMakernoteDirectory;
import au.com.lastweekend.jim.io.exif.makernote.minolta.MinoltaMakernoteDirectory;
import au.com.lastweekend.jim.io.exif.makernote.nikon.NikonType1MakernoteDirectory;
import au.com.lastweekend.jim.io.exif.makernote.nikon.NikonType2MakernoteDirectory;
import au.com.lastweekend.jim.io.exif.makernote.nikon.NikonType3MakernoteDirectory;
import au.com.lastweekend.jim.io.jpeg.JpegProcessingException;
import au.com.lastweekend.jim.io.jpeg.JpegQuantisationTableDirectory;
import au.com.lastweekend.jim.io.jpeg.JpegReader;
import au.com.lastweekend.jim.io.jpeg.JpegStartOfFrameDirectory;
import au.com.lastweekend.jim.io.jpeg.JpegWriter;
import au.com.lastweekend.jim.io.metadata.Directory;
import au.com.lastweekend.jim.io.metadata.Metadata;

public abstract class Scaler {

    public boolean isOptimal() {
        // TODO Auto-generated method stub
        return false;
    }

    public void scale(File original, File scaled, Point newSize) {
        doScale(original, scaled, newSize);
        copyMetadata(original, scaled, newSize);
    }

    public abstract void doScale(File original, File scaled, Point newSize);

    private void copyMetadata(File origFile, File scaledFile, Point imageSize) {
        JpegWriter writer = new JpegWriter();
        JpegReader reader = new JpegReader();

        try {
            Metadata newMetadata = new Metadata();
            Metadata origMd = reader.readMetadata(origFile);
            Metadata scaledMd = reader.readImage(scaledFile);

            // only do any of this if we have EXIF data to transfer.
            if (hasExif(origMd)) {
                Iterator iter = origMd.getDirectoryIterator();
                while (iter.hasNext()) {
                    Directory dir = (Directory) iter.next();
                    // Copy over all exif related classes (JIM doesn't really have an OO way to 
                    // detect if a directory is EXIF related or not.
                    if (dir.getClass().getPackage().getName().indexOf("exif") >= 0) {
                        newMetadata.addDirectory(dir);
                    }
                }

                iter = scaledMd.getDirectoryIterator();
                while (iter.hasNext()) {
                    newMetadata.addDirectory((Directory) iter.next());
                }
                fixMetadata(newMetadata, imageSize.x, imageSize.y);
                writer.writeImage(newMetadata, scaledFile);
            }
        } catch (JpegProcessingException e) {
            MessageUtils.showErrorMessage(Messages.getString(
                    "juploadr.ui.rescale.could.not.scale", origFile.getName(), e.getMessage())); //$NON-NLS-1$
        }

    }

    private void fixMetadata(Metadata newMetadata, int width, int height) {
        Directory exif = newMetadata.getDirectory(ExifDirectory.class);
        if (exif != null) {
            exif.setTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT, TiffTagFormat.FMT_USHORT, new Integer(height));
            exif.setTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH, TiffTagFormat.FMT_USHORT, new Integer(width));
        }
    }

    private boolean hasExif(Metadata md) {
        Iterator iter = md.getDirectoryIterator();
        Package exifPackage = ExifDirectory.class.getPackage();
        while (iter.hasNext()) {
            Directory d = (Directory) iter.next();
            if (exifPackage.equals(d.getClass().getPackage())) {
                System.out.println("found EXIF");
                return true;
            }
        }
        return false;
    }
}
